using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using BlobSim.Shapes;

namespace BlobSim.Renderers
{
    class ReflectiveSurfaceRenderer
    {
        private TextureCube _cubemap;
        private Texture2D _whitePixel;
        private readonly EnvironmentMapEffect _effect;

        public ReflectiveSurfaceRenderer(GraphicsDevice device, ContentManager content, string path)
        {
            _effect = new EnvironmentMapEffect(device);
            LoadTextures(content, path);
        }

        private void LoadTextures(ContentManager content, string path)
        {
            _whitePixel = content.Load<Texture2D>("WhitePixel");
            _cubemap = content.Load<TextureCube>(path);
        }

        public void SetMatrices(Matrix worldMatrix, Matrix viewMatrix, Matrix projMatrix)
        {
            _effect.World = worldMatrix;
            _effect.View = viewMatrix;
            _effect.Projection = projMatrix;
        }

        public void Draw(Shape shape)
        {
            _effect.GraphicsDevice.SetVertexBuffer(shape.VertexBuffer);
            _effect.GraphicsDevice.Indices = shape.IndexBuffer;

            _effect.GraphicsDevice.DepthStencilState = DepthStencilState.Default;
            _effect.GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise;
            _effect.GraphicsDevice.BlendState = BlendState.Opaque;

            // clamp texture addressing for environment map
            _effect.GraphicsDevice.SamplerStates[1] = SamplerState.LinearClamp;

            _effect.Texture = _whitePixel;
            _effect.EnvironmentMap = _cubemap;
            _effect.EnvironmentMapAmount = 1;
            _effect.FresnelFactor = 0;

            foreach (var pass in _effect.CurrentTechnique.Passes)
            {
                pass.Apply();
                shape.Draw();
            }
        }
    }
}
